package com.example.mywiseelves.view;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.net.Uri;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.baidu.speech.EventListener;
import com.baidu.speech.EventManager;
import com.baidu.speech.EventManagerFactory;

import com.baidu.speech.asr.SpeechConstant;
import com.example.mywiseelves.R;
import com.example.mywiseelves.bean.ASRresponse;
import com.google.gson.Gson;


import java.lang.reflect.Field;
import java.util.Random;

/**
 * @author ZJK
 * @data 2021 13
 * @description
 */
public class ElvesView extends LinearLayout implements EventListener {

    //窗口管理，悬浮窗
    WindowManager mWindowManager;
    WindowManager.LayoutParams mLayoutParams;
    private EventManager asr;//语音识别核心库
    private int normalAnimId;
    private int eatAnimId;
    private int wisdom;
    private String openBrowser;
    private String openPhone;

    Context context;
    private ImageView myElves;
    //通知栏高度
    int mStatusBarHeight;
    //距离顶部偏移量
    int mOffsetToParent;
    //通知栏实际高度
    int mOffsetToParentY;

    //末时间
    private long mLastDownTime;

    //逻辑判断
    private boolean mIsNoMove = false;//长按3秒后，没有滑动
    private boolean mIsTouching = false;//长按下
    private boolean mIsLongTouching = false;//长按
    private boolean mIsSingleTouching = false;//单击
    private boolean mIsTwoTouching = false;//连续点击（500毫秒内连续点击）


    private long[] mHits = new long[2];

    //动画
    private AnimationDrawable animationDrawable;

    public ElvesView(Context context) {
        super(context);
        this.context = context;
        mStatusBarHeight= getStatusBarHeight();
        mOffsetToParent = dip2px(25);
        //获取顶部状态栏实际高度
        mOffsetToParentY = mStatusBarHeight + mOffsetToParent;
        mWindowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        //开始
        initView();
        //初始化界面控件的事件
        initEvent();
        //初始化EventManager对象
        asr = EventManagerFactory.create(context, "asr");
        //注册自己的输出事件类
        asr.registerListener(this); //  EventListener 中 onEvent方法

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        normal();

    }

    /**
     * 初始化界面的监听
     */
    private void initEvent() {
        myElves.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        //判断按下，长按
                        mIsTouching = true;
                        mIsLongTouching = false;
                        //没有连击
                        mIsTwoTouching = false;
                        //判断没有动
                        mIsNoMove = true;

                        //获取按下时间，按下位置
                        mLastDownTime = System.currentTimeMillis();

                        //3000毫秒后，判断是否长时间按住
                        postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                mIsLongTouching = isLongTouch();
                                if (mIsLongTouching) {
                                    try {
                                        myVoice();
                                    } catch (RemoteException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }, 3000);

                        break;

                    case MotionEvent.ACTION_MOVE:
                        //移动了
                        mIsNoMove = false;
                        break;
                    case MotionEvent.ACTION_UP:
                        //离开按下，不是长按
                        mIsTouching = false;
                        //判断连点
                        mIsTwoTouching = isTwoTouching();

                        //连续点击两次
                        if (mIsTwoTouching) {
                            //随机移动
                            randomMove();
                        }
                        postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                //单点击
                                mIsSingleTouching = isSingleTouch();
                                if (mIsSingleTouching) {
                                    //喂食
                                    eat();
                                    postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
                                            normal();
                                        }
                                    }, 4000);
                                }
                            }
                        }, 1000);

                }

                return true;
            }


        });
    }

    /**
     * 判断是否是长按模式。其中判断长按和没有动：
     */
    private boolean isLongTouch() {
        long time = System.currentTimeMillis();
        if (mIsTouching && mIsNoMove && (time - mLastDownTime >= 3000)) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否是单击模式，
     */
    private boolean isSingleTouch() {
        if (mIsLongTouching || mIsTwoTouching) {
            //长按或者连续点击
            return false;
        }
        return true;
    }

    /**
     * 判断是否连续点击模式。其中判断长按：
     */
    private boolean isTwoTouching() {
        System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
        mHits[mHits.length - 1] = SystemClock.uptimeMillis();
        if (mHits[0] >= (SystemClock.uptimeMillis() - 500)) {
            return true;
        }
        return false;
    }


    //初始化值
    private void initView() {
        inflate(getContext(), R.layout.view_elves, this);
        myElves = findViewById(R.id.my_elves);
    }

    /**
     * 从外界Service为Elves设置normalAnimId
     *
     * @param normalAnimId
     */
    public void setNormalAnimId(int normalAnimId) {
        this.normalAnimId = normalAnimId;
    }

    /**
     * 从外界Service为Elves设置eatAnimId
     *
     * @param eatAnimId
     */
    public void setEatAnimId(int eatAnimId) {
        this.eatAnimId = eatAnimId;
    }

    /**
     * 从外界Service为Elves设置wisdom
     */
    public void setVoice(int wisdom) {
        this.wisdom = wisdom;
    }

    /**
     * 从外界Service设置openBrowser
     */
    public void setOpenBrowser(String openBrowser) {
        this.openBrowser = openBrowser;
    }

    /**
     * 从外界Service设置openPhone
     */
    public void setOpenPhone(String openPhone) {
        this.openPhone = openPhone;
    }

    //获取悬浮窗
    public void setLayoutParams(WindowManager.LayoutParams params) {
        mLayoutParams = params;

    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        asr.send(SpeechConstant.ASR_CANCEL, "{}", null, 0, 0);
        //退出事件管理器
        // 必须与registerListener成对出现，否则可能造成内存泄露
        asr.unregisterListener(this);
    }

    /**
     * 获取通知栏高度
     *
     * @return
     */
    private int getStatusBarHeight() {
        int statusBarHeight = 0;
        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object o = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = (Integer) field.get(o);
            statusBarHeight = getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return statusBarHeight;
    }

    /**
     * 偏移
     */
    public int dip2px(float dip) {
        return (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, dip, getContext().getResources().getDisplayMetrics()
        );
    }

    /**
     * 常态动画
     */
    public void normal() {
        if (normalAnimId != 0) {
            myElves.setBackgroundResource(normalAnimId);
            animationDrawable = (AnimationDrawable) myElves.getBackground();
            animationDrawable.start();
        }

    }

    /**
     * 喂食动画
     */
    public void eat() {
        if (eatAnimId != 0) {
            Toast.makeText(context, "精灵正在进食", Toast.LENGTH_LONG).show();
            myElves.setBackgroundResource(eatAnimId);
            animationDrawable = (AnimationDrawable) myElves.getBackground();
            animationDrawable.start();
        }
    }

    /**
     * 喂食动画
     */
    public void myVoice() throws RemoteException {
        if (wisdom == 1) {
            asr.send(SpeechConstant.ASR_START, "{}", null, 0, 0);
            Toast.makeText(context, "精灵正在听取指令,5秒后结束", Toast.LENGTH_LONG).show();
            postDelayed(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(context, "精灵结束听取指令", Toast.LENGTH_LONG).show();
                    asr.send(SpeechConstant.ASR_STOP, "{}", null, 0, 0);
                }
            }, 5000);
        } else if (wisdom == 0) {
            Toast.makeText(context, "精灵智慧未开启", Toast.LENGTH_LONG).show();
        }


    }


    @Override
    public void onEvent(String s, String s1, byte[] bytes, int i, int i1) {
        if (s.equals(SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL)) {
            // 识别相关的结果都在这里
            if (s1 == null || s1.isEmpty()) {
                return;
            }
            if (s1.contains("\"final_result\"")) {
                Gson gson = new Gson();
                //数据解析转实体bean
                ASRresponse asRresponse = gson.fromJson(s1, ASRresponse.class);

                if (asRresponse != null) {
                    startApplication(asRresponse.getBest_result());
                }
            }
        }
    }

    /**
     * 语音启动应用
     */
    public void startApplication(String word) {
        if (word.contains(openBrowser)) {
            Toast.makeText(context, "口令:" + openBrowser + ",检验正确，打开浏览器", Toast.LENGTH_LONG).show();
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse("https://www.jluzh.edu.cn/"));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            getContext().startActivity(intent);
        } else if (word.contains(openPhone)) {
            Toast.makeText(context, "口令:" + openPhone + ",检验正确，拨打电话", Toast.LENGTH_LONG).show();
            Intent intent = new Intent(Intent.ACTION_DIAL);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.parse("tel:10086"));
            getContext().startActivity(intent);
        }
    }
    /**
     * 随机移动
     */
    public void randomMove(){
        Random r = new Random();
        int width=mWindowManager.getDefaultDisplay().getWidth();
        int height=mWindowManager.getDefaultDisplay().getHeight();
        int x = r.nextInt(width);
        int y= r.nextInt(height);
        mLayoutParams.x = (int) (x - mOffsetToParent);
        mLayoutParams.y = (int) (y - mOffsetToParentY);
        mWindowManager.updateViewLayout(this, mLayoutParams);
    }

}
